﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Project.Co_DataTransformationPrototype
{
    public class CascadeUpdatedMapping : MappingBase
    {
        private bool isNewValueTrue;

        public CascadeUpdatedMapping(EventContext eventContext, bool value)
        {
            this.eventContext = eventContext;
            this.isNewValueTrue = value;
        }

        internal override void generateSQLCodeMapping(StringBuilder existingScript = null)
        {
            strSQLMapping = new StringBuilder();

            if (existingScript != null)
                strSQLMapping.Append(existingScript);

            setCascadeUpdateSQLCode();

            strSQLMapping.AppendLine("GO" + Environment.NewLine);
        }

        private void setCascadeUpdateSQLCode()
        {
            Entity sourceEntity;
            Entity targetEntity;
            EntityAttribute attribute;
            EntityAssociation link = eventContext.elementEventArgs.ModelElement as EntityAssociation;
            string strSQL = @"/*** --- Updating FK-contraint for table {0} on column {1} --- ***/" + Environment.NewLine;
            string sqlText = string.Empty;

            attribute = link.Target.EntityAttributes.Find(att => att.CurrentName.Equals(link.AttributeInTarget));
            sourceEntity = link.Source;
            targetEntity = link.Target;

            strSQLMapping.AppendFormat(strSQL, targetEntity.CurrentName, attribute.CurrentName);

            // Remove existing FK constraint
            strSQLMapping.AppendFormat(@"ALTER TABLE [{0}].{1}" + Environment.NewLine, Data.DatabaseSettings.SHEMA_NAME, targetEntity.CurrentName);
            strSQLMapping.AppendFormat(@"    DROP CONSTRAINT FK_{0}_{1};" + Environment.NewLine, targetEntity.CurrentName, attribute.CurrentName);
            strSQLMapping.AppendLine("GO" + Environment.NewLine);

            // Recreate FK constraint with the needed cascade statements
            strSQLMapping.AppendFormat(@"ALTER TABLE [{0}].{1}" + Environment.NewLine, Data.DatabaseSettings.SHEMA_NAME, targetEntity.CurrentName);
            strSQLMapping.AppendFormat(@"    ADD CONSTRAINT FK_{0}_{1}" + Environment.NewLine, targetEntity.CurrentName, attribute.CurrentName);
            strSQLMapping.AppendFormat(@"        FOREIGN KEY ({0})" + Environment.NewLine, attribute.CurrentName);
            strSQLMapping.AppendFormat(@"        REFERENCES {0}", sourceEntity.CurrentName);

            if (link.DoCascadeDelete)
                sqlText = @"        ON DELETE CASCADE ";
            if (link.DoCascadeUpdate)
                sqlText += (sqlText == String.Empty ? @"        ON UPDATE CASCADE " : "ON UPDATE CASCADE ");

            if (sqlText != string.Empty)
                strSQLMapping.Append(Environment.NewLine + sqlText);

            strSQLMapping.Append(";" + Environment.NewLine);
        }
    }
}
